#ifndef _VL_SEMAPHORE__H_
#define _VL_SEMAPHORE__H_

#if defined __unix || defined __unix__ || __linux__ || __APPLE__ || defined __MACH__
	#define VL_POSIX
#else
	#error Unsupport platform...
#endif

#include <memory>

namespace VL {

/**
 * @Author: CimZzz
 * @Date: 2022-08-17 10:59:16
 * 
 * 信号量对象
 * 
 */
class Semphore {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:02:20
	 * 
	 * 构造方法
	 * 
	 * @param key 值指针
	 * @param notCreate 不存在信号量的时候是否进行创建
	 */
	explicit Semphore(std::shared_ptr<void> keyPtr, bool notCreate = false);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:02:20
	 * 
	 * 构造方法
	 * 
	 * @param key 值指针
	 * @param numsOfSem 信号量数量
	 * @param semArray 信号量初始值数组
	 * @param notCreate 不存在信号量的时候是否进行创建
	 */
	explicit Semphore(std::shared_ptr<void> keyPtr, int numsOfSem, unsigned short * semArray, bool notCreate = false);
	
	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:02:37
	 * 
	 * 析构函数
	 */
	~Semphore();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:17:27
	 * 
	 * 初始化信号量
	 * 
	 * @return 初始化成功返回 true
	 */
	bool initSemphore();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 17:23:01
	 * 
	 * 标记需要创建信号量
	 */
	void markNeedCreate();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 15:18:56
	 * 
	 * 标记为不创建信号量
	 */
	void markNotCreate();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:32:45
	 * 
	 * 信号量 P 操作
	 * 
	 * @param index 信号量下标
	 * 
	 * @note 如果只有一个信号量, index 参数将会被忽略
	 * 
	 * @return 执行成功返回 true
	 */
	bool p(uint16_t index = 0);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:32:59
	 * 
	 * 信号量 V 操作
	 * 
	 * @param index 信号量下标
	 * 
	 * @note 如果只有一个信号量, index 参数将会被忽略
	 * 
	 * @return 执行成功返回 true
	 */
	bool v(uint16_t index = 0);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 16:07:38
	 * 
	 * 释放信号量
	 * 
	 * @return 释放成功返回 true
	 */
	bool release();

#ifdef VL_POSIX

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:48:55
	 * 
	 * 生成信号量 Key 值
	 * 
	 * @param path 项目路径
	 * @param id 项目编号
	 * 
	 * @return 信号量 Key 值
	 */
	static std::shared_ptr<void> generateKey(const char * path, int id);

#endif //VL_POSIX


private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:17:43
	 * 
	 * 判断信号量是否已经被初始化
	 */
	bool isInited;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 12:22:23
	 * 
	 * 是否自动释放信号量
	 */
	bool notCreate;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:34:43
	 * 
	 * 信号量数量
	 */
	int numsOfSem;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 18:17:43
	 * 
	 * 信号量初始值数组
	 */
	std::shared_ptr<unsigned short> semArr;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:01:43
	 * 
	 * 信号量 Key 值
	 */
	std::shared_ptr<void> key;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-08-17 11:02:57
	 * 
	 * 信号量 id
	 */
	std::shared_ptr<void> semId;
};

}

#endif // _VL_SEMAPHORE__H_
